<template>
  <div id="page">
    <ul class="page_box">
      <li class="prev" @click="prevClick">上一页</li>
      <li
        class="page"
        v-for="item in pages"
        :key="item"
        :class="{ pageActive: currentPage === item }"
        @click="pageClick(item)"
      >
        {{ item }}
      </li>
      <li class="next" @click="nextClick">下一页</li>
    </ul>
  </div>
</template>

<script>
import {
  defineComponent,
  reactive,
  toRefs,
  computed,
  onMounted,
  watchEffect,
} from "vue";
export default defineComponent({
  name: "Page",
  props: {
    // 每一页显示的数据数量
    pageNum: {
      type: Number,
      default: 0,
      require: true,
    },
    // 数据总量
    totalData: {
      type: Number,
      default: 0,
      require: true,
    },
  },
  setup(props, context) {
    let data = reactive({
      currentPage: 1, // 当前页码
      totalPage: 0, // 总页码
      pages: 0, // 遍历的页码
    });

    let manageTotalPage = () => {
      if (props.totalData <= props.pageNum) {
        // 如果总数据量小于等于每页展现的数据量时，意味只有一页的数据，因此总页码为一页
        data.totalPage = 1;
      } else {
        if (props.totalData % props.pageNum == 0) {
          // 如果总数据量与每页展现的数据量进行取余等于0，意味总页码就是该取余后的值
          data.totalPage = props.totalData / props.pageNum;
        } else {
          // 如果不为0，意味着取余后的值并不能完全存放所有的数据，那么进行向下取整后加上一页用于放剩余的数据
          data.totalPage = parseInt(props.totalData / props.pageNum) + 1;
        }
        return data.totalPage;
      }
    };

    // 初始化后整理页码
    onMounted(() => {
      manageTotalPage();
    });

    // 数据更新后整理页码
    watchEffect(() => {
      manageTotalPage();
    });

    // 整理页码
    data.pages = computed(() => {
      // 当总页码数量小于7页时，直接展现页码
      if (data.totalPage < 7) return data.totalPage;

      if (data.currentPage < 5) {
        // 如果总页码大于7页，那么大量页码的情况下要考虑进行省略页码展现
        return [1, 2, 3, 4, 5, "...", data.totalPage];
      } else if (data.currentPage > data.totalPage - 5) {
        return [
          1,
          "...",
          data.totalPage - 4,
          data.totalPage - 3,
          data.totalPage - 2,
          data.totalPage - 1,
          data.totalPage,
        ];
      } else {
        return [
          1,
          "...",
          data.currentPage,
          data.currentPage + 1,
          data.currentPage + 2,
          data.currentPage + 3,
          "...",
          data.totalPage,
        ];
      }
    });

    // 点击上一页回调
    let prevClick = () => {
      if (data.currentPage == 1) {
        return;
      }
      data.currentPage -= 1;
      // 通知父组件改变页码数据
      context.emit("changePage", data.currentPage);
    };

    // 点击下一页回调
    let nextClick = () => {
      if (data.currentPage == data.totalPage) {
        return;
      }
      data.currentPage += 1;
      context.emit("changePage", data.currentPage);
    };

    // 点击页码回调
    let pageClick = (page) => {
      if (page == "...") return;
      if (data.currentPage == page) {
        return;
      }
      data.currentPage = page;
      context.emit("changePage", data.currentPage);
    };

    return {
      ...toRefs(data),
      prevClick,
      nextClick,
      pageClick,
    };
  },
});
</script>
<style scoped>
#page {
  width: 100%;
  margin: 10px 0;
}
.page_box {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}
li {
  list-style: none;
  padding: 8px;
  background-color: #fff;
  color: #222;
  font-size: 12px;
  border: 1px solid #ccc;
  border-radius: 4px;
  margin: 0 5px;
  cursor: pointer;  
  white-space: nowrap;
}

.pageActive {
  color: #fff;
  background-color: #ec4141 !important;
}
</style>
